package com.heima.wemedia.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.heima.common.constants.KafkaMessageConstants;
import com.heima.feign.article.ArticleFeignClient;
import com.heima.model.article.entity.ApArticle;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.dto.NewsAuthDto;
import com.heima.model.wemedia.dto.WmNewsDto;
import com.heima.model.wemedia.dto.WmNewsPageReqDto;
import com.heima.model.wemedia.entity.WmMaterial;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.model.wemedia.entity.WmUser;
import com.heima.wemedia.Vo.WmNewsVo;
import com.heima.wemedia.dao.WmUserDao;
import com.heima.wemedia.utils.WmThreadLocalUtil;
import com.heima.wemedia.dao.WmMaterialDao;
import com.heima.wemedia.dao.WmNewsDao;
import com.heima.wemedia.dao.WmNewsMaterialDao;
import com.heima.wemedia.service.WmNewsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 自媒体文章表(WmNews)表服务实现类
 *
 * @author makejava
 * @since 2022-04-12 16:23:07
 */
@Service("wmNewsService")
public class WmNewsServiceImpl implements WmNewsService {
    @Resource
    private WmNewsDao wmNewsDao;

    @Resource
    private WmNewsMaterialDao wmNewsMaterialDao;

    @Resource
    private WmMaterialDao wmMaterialDao;

    @Resource
    private KafkaTemplate kafkaTemplate;

    @Resource
    private ArticleFeignClient articleFeignClient;

    @Resource
    private WmUserDao wmUserDao;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public WmNews queryById(Long id) {
        return this.wmNewsDao.queryById(id);
    }

    /**
     * 新增数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
    @Override
    public WmNews insert(WmNews wmNews) {
        this.wmNewsDao.insert(wmNews);
        return wmNews;
    }

    /**
     * 修改数据
     *
     * @param wmNews 实例对象
     * @return 实例对象
     */
    @Override
    public WmNews update(WmNews wmNews) {
        this.wmNewsDao.update(wmNews);
        return this.queryById(wmNews.getId());
    }

    /**
     * 发布文章
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult submit(WmNewsDto dto) {
        //1.参数校验
        if (dto == null || StringUtils.isBlank(dto.getTitle())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        //2.封装数据     type  images
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto, wmNews);
        //2.1获取内容中的图片
        String content = dto.getContent();
        //2.1.1 内容转为map集合
        List<Map> maps = JSON.parseArray(content, Map.class);
        //2.1.2获取内容图片集合
        List<String> contentImages = maps.stream()
                //过滤map集合中type值为image的
                .filter(map -> "image".equals(map.get("type")))
                //获取map集合中value的值,并收集为新的集合
                .map(map -> map.get("value").toString())
                .collect(Collectors.toList());
        //2.2获取封面图片集合
        List<String> coverImages = dto.getImages();
        //2.3封装type数据
        // type值为 -1时
        if (dto.getType() == -1) {
            if (contentImages.size() >= 3) {
                //内容图片>3时，type=3  封面图片取3张
                coverImages = contentImages.stream().limit(3).collect(Collectors.toList());
                wmNews.setType(3);
            } else if (contentImages.size() >= 1 && contentImages.size() < 3) {
                //0<内容图片<3时，type=1  封面图片取1张
                coverImages = contentImages.stream().limit(1).collect(Collectors.toList());
                wmNews.setType(1);
            } else {
                //内容图片=0时，type=0 封面图片取为空
                coverImages = Collections.emptyList();
                wmNews.setType(0);
            }
        }
        //2.4封装封面图片数据   ---》将集合转为字符串，中间用逗号分隔
        if (CollectionUtils.isNotEmpty(coverImages)) {
            wmNews.setImages(StringUtils.join(coverImages, ","));
        }

        //3.保存文章数据   新增  修改
        saveOrUpdate(wmNews);

        //4.保存文章和素材关系表
        //4.1保存文章和封面素材关系表
        saveCoverImageRelation(wmNews, coverImages);
        //4.2保存文章和内容素材关系表
        saveContentImageRelation(wmNews, contentImages);

        //发送审核消息
        kafkaTemplate.send(KafkaMessageConstants.WM_NEWS_AUTO_SCAN_TOPIC, wmNews.getId().toString());
        return ResponseResult.okResult("发布成功");
    }

    /**
     * 文章内容列表展示
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list(WmNewsPageReqDto dto) {
        //1.参数校验
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        //2.封装查询条件
        Map<String, Object> queryParam = BeanUtil.beanToMap(dto);
        queryParam.put("userId", WmThreadLocalUtil.getId());
        //3.执行查询
        PageHelper.startPage(dto.getPage(), dto.getSize());
        Page<WmNews> page = wmNewsDao.queryByMap(queryParam);
        //4.封装数据返回
        ResponseResult result = new PageResponseResult(page.getPageNum(), page.getPageSize(), (int) page.getTotal());
        result.setData(page.getResult());
        return result;
    }

    /**
     * 删除文章
     *
     * @param id
     * @return
     */
    @Override
    public ResponseResult deleteById(Long id) {
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "文章id缺少");
        }
        //根据id获取数据
        WmNews wmNews = wmNewsDao.queryById(id);
        //判断文章状态
        if (wmNews == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        if (wmNews.getStatus() == 9) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH, "文章已发布, 不能删除!");
        }
        //删除文章表
        wmNewsDao.deleteById(id);
        //删除文章素材关系表
        wmNewsMaterialDao.deleteByNewsId(id);
        return ResponseResult.okResult("删除文章成功");
    }

    /**
     * 运营管理文章列表展示
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult list_vo(NewsAuthDto dto) {
        //1.参数校验
        if (dto == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        dto.checkParam();
        //2.封装查询条件
        Map<String, Object> queryParam = BeanUtil.beanToMap(dto);

        //3.执行查询
        PageHelper.startPage(dto.getPage(), dto.getSize());
        Page<WmNews> page = wmNewsDao.queryAllScan(queryParam);
        //4.封装数据返回
        ResponseResult result = new PageResponseResult(page.getPageNum(), page.getPageSize(), (int) page.getTotal());
        List<WmNews> list = page.getResult();
        List<WmNewsVo> wmNewsVoList = list.stream().map(wmNews -> {
            WmNewsVo wmNewsVo = new WmNewsVo();
            BeanUtils.copyProperties(wmNews, wmNewsVo);
            wmNewsVo.setSubmitedTime(wmNews.getUpdatedTime());
            //通过newsId查询ap_article文章表
            //feign远程调用
            ApArticle apArticle = articleFeignClient.queryByNewsId(wmNews.getId());
            if (apArticle != null) {
                wmNewsVo.setArticleId(apArticle.getId());
                wmNewsVo.setAuthorName(apArticle.getAuthorName());
            }
            if (wmNewsVo.getAuthorName() == null) {
                WmUser wmUser = wmUserDao.queryById(wmNewsVo.getUserId());
                wmNewsVo.setAuthorName(wmUser.getNickname());
            }
            return wmNewsVo;
        }).collect(Collectors.toList());
        result.setData(wmNewsVoList);
        return result;
    }

    /**
     * 查询文章详情
     * @param id
     * @return
     */
    @Override
    public ResponseResult one_vo(Long id) {
        //1.参数校验
        if (id == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        WmNews wmNews = wmNewsDao.queryById(id);
        WmNewsVo wmNewsVo = new WmNewsVo();
        BeanUtils.copyProperties(wmNews, wmNewsVo);
        wmNewsVo.setSubmitedTime(wmNews.getUpdatedTime());
        //通过newsId查询ap_article文章表
        //feign远程调用
        ApArticle apArticle = articleFeignClient.queryByNewsId(wmNews.getId());
        if (apArticle != null) {
            wmNewsVo.setArticleId(apArticle.getId());
            wmNewsVo.setAuthorName(apArticle.getAuthorName());
        }
        if (wmNewsVo.getAuthorName() == null) {
            WmUser wmUser = wmUserDao.queryById(wmNewsVo.getUserId());
            wmNewsVo.setAuthorName(wmUser.getNickname());
        }
        return ResponseResult.okResult(wmNewsVo);
    }

    /**
     * 人工审核
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult ManualAudit(NewsAuthDto dto) {
        //1.参数校验
        if (dto == null || dto.getId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        WmNews wmNews = new WmNews();
        BeanUtils.copyProperties(dto,wmNews);
        wmNews.setReason(dto.getMsg());
        wmNewsDao.update(wmNews);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 保存文章和内容素材关系表
     *
     * @param wmNews
     * @param contentImages
     */
    private void saveContentImageRelation(WmNews wmNews, List<String> contentImages) {
        if (CollectionUtils.isEmpty(contentImages)) {
            return;
        }
        saveImageRelation(wmNews, contentImages, 1);
    }

    /**
     * 保存文章和封面素材关系表
     *
     * @param wmNews
     * @param coverImages
     */
    private void saveCoverImageRelation(WmNews wmNews, List<String> coverImages) {
        if (CollectionUtils.isEmpty(coverImages)) {
            return;
        }
        saveImageRelation(wmNews, coverImages, 0);
    }

    /**
     * 保存文章和素材关系表
     */
    private void saveImageRelation(WmNews wmNews, List<String> images, int type) {
        //1.1根据素材路径获取素材ID
        images = images.stream().distinct().collect(Collectors.toList());
        List<WmMaterial> materials = wmMaterialDao.queryByUrls(images);
        //获取素材ID
        List<Long> ids = materials.stream().map(map -> map.getId()).collect(Collectors.toList());
        //判断素材是否缺失
        if (images.size() != ids.size()) {
            throw new RuntimeException("素材图片缺失");
        }
        //保存保存文章和素材的关系
        // insert into wm_news_material () values (),(),()
        wmNewsMaterialDao.saveNewsRelation(wmNews.getId(), ids, type);
    }

    /**
     * 保存文章数据
     *
     * @param wmNews
     */
    private void saveOrUpdate(WmNews wmNews) {
        //组装参数
        wmNews.setUserId(WmThreadLocalUtil.getId());
        wmNews.setEnable(1);
        wmNews.setUpdatedTime(new Date());
        //判断id是否存在，存在修改，不存在新增
        if (wmNews.getId() == null) {
            //新增
            wmNews.setCreatedTime(new Date());
            wmNewsDao.insert(wmNews);
        }
        //修改
        wmNewsDao.update(wmNews);
        //删除文章和素材关系表
        wmNewsMaterialDao.deleteByNewsId(wmNews.getId());
    }
}
